home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C -*- */
- /* EditForm.cc - EditForm class - editing form.
- * Created by Robert Heller on Thu Dec 12 19:29:12 1991
- *
- * ------------------------------------------------------------------
- * Home Libarian by Deepwoods Software
- * Common Class library implementation code
- * ------------------------------------------------------------------
- * Modification History:
- * ------------------------------------------------------------------
- * Contents:
- * ------------------------------------------------------------------
- *
- *
- * Copyright (c) 1991,1992 by Robert heller (D/B/A Deepwoods Software)
- * All Rights Reserved
- *
- */
-
- #include <EditForm.h>
- #include <fstream.h>
- #include <osfcn.h>
- #include <unistd.h>
- #ifdef OSK
- #define O_RDONLY S_IREAD
- #endif
-
- char EditForm::EditorCommand[48];
- Boolean EditForm::EditorCmdInit;
-
- void EditForm::HiliteField(int fieldno,Boolean hilite)
- {
- int row = fields[fieldno-1].row;
- int col = fields[fieldno-1].col;
- int width = fields[fieldno-1].width;
- int height = fields[fieldno-1].height;
- char* s;
- char temp[80];
- switch (fields[fieldno-1].type) {
- case Literal:
- case String:
- case EditorString: s = (char*) fields[fieldno-1].fieldp; break;
- case Int: sprintf(temp,"%d",*((int*)fields[fieldno-1].fieldp));
- s = temp;break;
- case Float: sprintf(temp,"%f",*((float*)fields[fieldno-1].fieldp));
- s = temp;break;
- case Special: s = (*fields[fieldno-1].ftos)(fields[fieldno-1].fieldp);break;
- }
- Terminal::term->PenPos(row,col);
- if (hilite) Terminal::term->RevsPen();
- else Terminal::term->PlainPen();
- Terminal::term->PutStrInBox(row,col,width,height,s);
- if (!hilite) Terminal::term->RevsPen();
- else Terminal::term->PlainPen();
- Terminal::term->PenPos(row,col);
- }
-
- EditForm::EditForm(char* title,int fieldcount,Field* infields,int bindcount,
- KeyBinding* inbinds)
- {
- if (!EditorCmdInit) {
- char* p = getenv("EDITOR");
- if (p == 0) strcpy(EditorCommand,DEFAULTEDITOR);
- else strcpy(EditorCommand,p);
- EditorCmdInit = true;
- }
- strcpy(Title,title);
- fields = new Field[fieldcount];
- nFields = fieldcount;
- for (int i = 0;i < fieldcount;i++) {
- fields[i] = infields[i];
- if (fields[i].height <= 0) fields[i].height = 1;
- }
- nBinds = bindcount;
- if (bindcount > 0) {
- bindings = new KeyBinding[bindcount];
- for (i = 0;i < bindcount;i++) bindings[i] = inbinds[i];
- }
- currentField = 0;
- for (i = 0;i < nFields;i++) {
- if (fields[i].type != Literal) {
- currentField = i+1;
- break;
- }
- }
- }
-
- EditForm::~EditForm()
- {
- delete fields;
- if (nBinds > 0) delete bindings;
- }
-
- void EditForm::RePaint()
- {
- int c = (Terminal::term->colms - strlen(Title)) >> 1;
- Terminal::term->Clear();
- Terminal::term->RevsPen();
- Terminal::term->PutStrAt(1,c,Title);
- Terminal::term->PlainPen();
- for (int i = 0;i < nFields;i++) {
- char* s;
- char temp[80];
- switch (fields[i].type) {
- case Literal:
- case EditorString:
- case String: s = (char*) fields[i].fieldp;
- break;
- case Int: sprintf(temp,"%d",*((int*)fields[i].fieldp));
- s = temp;break;
- case Float: sprintf(temp,"%f",*((float*)fields[i].fieldp));
- s = temp;break;
- case Special: s = (*fields[i].ftos)(fields[i].fieldp);break;
- }
- if ((i+1) == currentField) Terminal::term->RevsPen();
- Terminal::term->PutStrInBox(fields[i].row,fields[i].col,
- fields[i].width,fields[i].height,s);
- if ((i+1) == currentField) Terminal::term->PlainPen();
- }
- if (IsModified) Terminal::term->PutCharAt(0,0,'*');
- Terminal::term->PenPos(fields[currentField-1].row,
- fields[currentField-1].col);
- }
-
- Boolean EditForm::RunForm()
- {
- RePaint();
- for (;;) {
- int nFld,next,key,i;
- static char buffer[80];
- Field* fld = &fields[currentField-1];
- switch (key = Terminal::term->GetKey()) {
- case upCmd:
- case leftCmd:
- if (currentField > 1) {
- for (nFld = currentField-1;
- nFld > 0 && fields[nFld-1].type == Literal;
- nFld--) ;
- if (nFld > 0 && fields[nFld-1].type != Literal) next = nFld;
- else next = 0;
- } else next = 0;
- break;
- case 'i':
- case 'I': switch (fld->type) {
- case String:
- Terminal::term->GetLine((char*)fld->fieldp,
- fld->width);
- break;
- case Int:
- Terminal::term->GetLine(buffer,fld->width);
- *((int*)(fld->fieldp)) = atoi(buffer);
- break;
- case Float:
- Terminal::term->GetLine(buffer,fld->width);
- *((float*)(fld->fieldp)) = atof(buffer);
- break;
- case Special:
- Terminal::term->GetLine(buffer,fld->width);
- (*fld->stof)(buffer,fld->fieldp);
- break;
- case EditorString:
- {
- static char tempname[] = "EDXXXXXX";
- static char tname[32];
- strcpy(tname,mktemp(tempname));
- {ofstream file;
- file.open(tname);
- file << ((char*)fld->fieldp);
- file.close();
- }
- static char* editargs[] = {
- EditorCommand,
- tname,
- 0
- };
- int status = Terminal::term->forkprog(editargs);
- if (status == 1) {
- #ifdef USETREAM
- ifstream file;
- file.open(tname);
- file.seekg(0,ios::end);
- streampos size = file.tellg();
- cerr << "*** file size=" << size << "\n";
- file.seekg(0,ios::beg);
- if ((size+1) > fld->buffersize)
- size = fld->buffersize-1;
- file.read(fld->fieldp,size);
- //file >> ((char [size])(fld->fieldp));
- file.close();
- #else
- int fd;
- fd = open(tname,O_RDONLY);
- int size = lseek(fd,0L,SEEK_END);
- lseek(fd,0L,SEEK_SET);
- if ((size+1) > fld->buffersize)
- size = fld->buffersize-1;
- read(fd,fld->fieldp,size);
- close(fd);
- #endif
- unlink(tname);
- *(((char*)(fld->fieldp))+size) = '\0';
- RePaint();
- } else if (status == 0) {
- Terminal::term->PutStrAt(0,0,"Hit any key to continue");
- Terminal::term->GetKey();
- RePaint();
- unlink(tname);
- continue;
- } else {
- unlink(tname);
- continue;
- }
- }
- break;
- }
- IsModified = true;
- Terminal::term->PutCharAt(0,0,'*');
- case downCmd:
- case rightCmd:
- case '\t':
- if (currentField < nFields) {
- for (nFld = currentField+1;
- nFld < nFields && fields[nFld-1].type == Literal;
- nFld++) ;
- if (fields[nFld-1].type != Literal) next = nFld;
- else next = 0;
- } else next = 0;
- break;
- case escCmd: return(IsModified);
- case '\014': RePaint(); break;
- case '?':
- Terminal::term->Clear();
- Terminal::term->PutStrAt(2,0,"Global Key bingings:");
- Terminal::term->PutStrAt(4,0,"UP,LEFT: Previous field");
- Terminal::term->PutStrAt(5,0,"i,I: Insert/update field");
- Terminal::term->PutStrAt(6,0,"DOWN,RIGHT,TAB: Next field");
- Terminal::term->PutStrAt(7,0,"HOME: Exit");
- Terminal::term->PutStrAt(8,0,"^L: Repaint");
- Terminal::term->PutStrAt(9,0,"?: This screen");
- Terminal::term->PutStrAt(11,0,"Local Key Bindings");
- for (i = 0;i < nBinds;i++) {
- Terminal::term->PutStrAt(13+i,0,bindings[i].docstring);
- }
- Terminal::term->PutStrAt(0,0,"Hit any key to resume editing:");
- Terminal::term->GetKey();
- RePaint();
- continue;
- default:
- for (i = 0;i < nBinds;i++) {
- if (key == bindings[i].keycode) break;
- }
- if (i == nBinds) Terminal::term->Bell();
- else (*bindings[i].fun)(*this);
- continue;
- }
- if (next == 0) Terminal::term->Bell();
- else {
- HiliteField(currentField,false);
- fld = &fields[(currentField = next) - 1];
- HiliteField(currentField,true);
- }
- }
- }
-
-
-